package com.ryx.service.Impl;

import com.github.pagehelper.PageHelper;
import com.ryx.entity.SysFile;
import com.ryx.entity.SysRotationChart;
import com.ryx.exception.GlobalException;
import com.ryx.exception.code.BaseResponseCode;
import com.ryx.mapper.SysFileMapper;
import com.ryx.service.FileService;
import com.ryx.utils.PageUtil;
import com.ryx.vo.req.FilePageReqVo;
import com.ryx.vo.resp.PageVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @BelongsPackage: com.ryx.service.Impl
 * @Author: 容永轩
 * @CreateTime: 2021-01-28
 * @Description:
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {


    @Value("${file.path}")
    public String filePath;

    @Value("${file.base-url}")
    private String baseUrl;

    @Autowired
    private SysFileMapper fileMapper;


    /**
     *
     * @param file 要上传的文件
     * @param createId 上传的用户id
     * @param type   文件类型（1：其他类型文件；2:轮播图片；3：视频文件）
     * @return  String
     */
    @Override
    public String upload(MultipartFile file, String createId, Integer type) {

        //文件原始名
        String originalFilename = file.getOriginalFilename();

        assert originalFilename != null;
        //拿到后缀名
        String extensionName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        //file的id主键
        String fileId = UUID.randomUUID().toString().replace("-","");
        //file新的Name
        String fileName =fileId+"."+extensionName;

        //创建文件路径  F:/logs/cache/images/·fileName·
        File destFile = new File(filePath + fileName);

        if (!destFile.getParentFile().exists()){
            //如果不存在就创建
            destFile.getParentFile().mkdirs();
        }

        //http://localhost:8080/upload/image/xxx.xxx
        String fileUrl=baseUrl+fileName;
        try {

            log.info("baseUrl:{}",fileUrl);

            //保存文件  写入文件
            file.transferTo(destFile);

            SysFile sysFile=new SysFile();
            sysFile.setId(UUID.randomUUID().toString());
            sysFile.setFileName(fileName);
            sysFile.setOriginalName(originalFilename);
            sysFile.setExtensionName(extensionName);
            sysFile.setCreateId(createId);
            sysFile.setType(type);
            sysFile.setFileUrl(fileUrl);
            sysFile.setCreateTime( new Date());
//            sysFile.setFileUrl("");

            //流长度
            sysFile.setSize(FileUtils.byteCountToDisplaySize(file.getSize()));

            //插入数据到DB
            int i = fileMapper.insertSelective(sysFile);
            if(i!=1){
                throw new GlobalException(BaseResponseCode.OPERATION_ERROR);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("e:{}",e.getMessage());
            throw new GlobalException(BaseResponseCode.UPLOAD_FILE_ERROR);
        }

        return fileUrl;
    }

    @Override
    public void downloadFile(String fileId, HttpServletResponse response) {
        SysFile sysFile = fileMapper.selectByPrimaryKey(fileId);

        if (sysFile == null){
            throw new GlobalException(BaseResponseCode.DATA_ERROR);
        }

        //设置响应头部 设置他的类型
        /*
        文件下载响应头的设置
            content-type 指示响应内容的格式
            content-disposition 指示如何处理响应内容。
            一般有两种方式：
            inline ：直接在页面显示
            attchment ：以附件形式下载
         */
        try {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            byte[] bytes = sysFile.getOriginalName().getBytes(StandardCharsets.UTF_8);
            String fileName = new String(bytes, StandardCharsets.ISO_8859_1);

            response.setHeader("content-disposition",String.format("attachment;filename=%s",fileName));

        } catch (Exception e) {
            throw new GlobalException(BaseResponseCode.OPERATION_ERROR);
        }

        ServletOutputStream outputStream = null;
        //写入操作
        try {
            File file = new File(filePath+sysFile.getFileName());
            outputStream =response.getOutputStream();
            IOUtils.write(FileUtils.readFileToByteArray(file),outputStream);
        } catch (IOException e) {
            throw new GlobalException(BaseResponseCode.OPERATION_ERROR);
        }finally {
            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    @Override
    public int deleteFile(String fileUrl) {

        //删除文件信息表里面的数据
        int i = fileMapper.deleteByFileUrl(fileUrl);
        if (i<=0){
            throw new GlobalException(BaseResponseCode.OPERATION_ERROR);
        }

        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/")+1);

        //删除磁盘文件  根据图片地址删除数据库存储文件信息
        File file = new File(filePath + fileName);
        if (file.exists()){
            file.delete();
        }

        return  i;
    }

    @Override
    public PageVo<SysRotationChart> pageInfo(FilePageReqVo vo, String userId) {

        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());

        List<SysFile> sysFiles = fileMapper.selectByUserId(userId);

        return PageUtil.getPageVo(sysFiles);
    }


}
